package com.liao.badminton.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.hutool.core.util.ObjectUtil;
import com.liao.badminton.code.*;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.liao.badminton.dto.StatDto;
import com.liao.badminton.entity.UserGroupRef;
import com.liao.badminton.redis.RedisEnum;
import com.liao.badminton.redis.RedisUtil;
import com.liao.badminton.code.util.EntityUtils;
import com.liao.badminton.code.util.CheckUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.liao.badminton.entity.BoutStat;
import com.liao.badminton.dto.BoutStatDto;
import com.liao.badminton.service.UserGroupRefService;
import com.liao.badminton.vo.BoutStatVo;
import com.liao.badminton.mapper.BoutStatMapper;
import com.liao.badminton.service.BoutStatService;
import com.liao.badminton.vo.RankStatVo;
import com.liao.badminton.vo.StatVo;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

import lombok.extern.log4j.Log4j2;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import static cn.hutool.core.util.ObjectUtil.isNotEmpty;
import static com.liao.badminton.code.util.CheckUtil.checkValue;

/**
 * @author liaocheng
 * @date 2024-10-31
 * description:录入对局统计表
 */
@Component
@Log4j2
public class BoutStatServiceImpl extends ServiceImpl<BoutStatMapper, BoutStat> implements BoutStatService {
    @Resource
    private UserGroupRefService userGroupRefService;

    /**
     * 新增
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, timeout = 10, rollbackFor = Exception.class)
    public ResponseRest<Long> saveBoutStat(BoutStatDto param) throws ProjectException {
        BoutStat boutStat = param.invertEntity();
        EntityUtils.setCreatAndUpdateInfo(boutStat);
        this.save(boutStat);
        return ResponseRest.suc("saveBoutStat", boutStat.getId());
    }

    /**
     * 删除
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, timeout = 10, rollbackFor = Exception.class)
    public ResponseRest<Boolean> deletesBoutStat(BoutStatDto param) throws ProjectException {
        boolean bool = this.removeByIds(param.getDelIds());
        if (bool) {
            param.getDelIds().forEach(id -> RedisUtil.toDelete(RedisEnum.CACHE_TABLE_DATA, "boutStat", "id", id));
        }
        return ResponseRest.suc("deletesBoutStat", true);
    }

    /**
     * 查询列表
     */
    @Override
    public ResponseRest findBoutStatByPageParam(PageParam<BoutStatDto> pageParam) throws ProjectException {
        checkValue(pageParam, "pageParam");
        ResponseRest resp = ResponseRest.suc("findBoutStatByPageParam");
        PageHelper.startPage(pageParam.getCurrent(), pageParam.getSize());
        List<BoutStatVo> list = baseMapper.findByPageParam(pageParam);
        resp.setData(new PageInfo<>(list));
        return resp;
    }

    /**
     * 查询详情
     */
    @Override
    public ResponseRest findDetail(BoutStatDto param) throws ProjectException {
        Object getDate = RedisUtil.toGetDate(RedisEnum.CACHE_TABLE_DATA, "boutStat", "id", param.getId());
        if (isNotEmpty(getDate)) {
            RedisUtil.toFlushExpire(RedisEnum.CACHE_TABLE_DATA, "boutStat", "id", param.getId());
            return ResponseRest.suc("findDetail", (BoutStatVo) getDate);
        }
        BoutStatVo vo = null;
        BoutStat db = this.getById(param.getId());
        if (isNotEmpty(db)) {
            vo = BoutStatVo.invertToVo(db);
            RedisUtil.toSaveRedis(RedisEnum.CACHE_TABLE_DATA, "boutStat", "id", param.getId(), vo, null);
        }
        return ResponseRest.suc("findDetail", vo);
    }

    @Override
    public List<BoutStat> findByDto(BoutStatDto param) {
        LambdaQueryWrapper<BoutStat> query = new LambdaQueryWrapper<>();
        if (isNotEmpty(param.getImportRecordId())) {
            query.eq(BoutStat::getImportRecordId, param.getImportRecordId());
        }
        return this.list(query);
    }

    @Override
    public void deleteByImportRecordId(Long importRecordId) throws ProjectException {
        this.remove(new LambdaQueryWrapper<BoutStat>().eq(BoutStat::getImportRecordId, importRecordId));
    }

    @Override
    public void deleteByImportRecordIdHard(Long importRecordId) {
        this.baseMapper.deleteByImportId(importRecordId);
    }

    @Override
    public ResponseRest<StatVo> personalStat(StatDto param) {
        checkValue(param, "param");
//        CheckUtil.checkValue(param.getType(), 1, "传入的查询类型不正确，type只能为1");
        if (ObjectUtil.isEmpty(param.getUserGroupRefId())) {
            checkValue(param.getGroupId(), "查询群id不能为空");
            checkValue(param.getTeamOneName(), "查询对象名称不能为空");
            UserGroupRef one = userGroupRefService.getOne(new LambdaQueryWrapper<UserGroupRef>().eq(UserGroupRef::getGroupId, param.getGroupId())
                    .eq(UserGroupRef::getUserName, param.getTeamOneName()));
            CheckUtil.checkDbNotData(one, "查询对象不存在");
            param.setUserGroupRefId(one.getId());
        }
        checkValue(param.getUserGroupRefId(), "查询对象id不能为空");

        StatVo statVo = baseMapper.findPersonalStat(param);
        if (isNotEmpty(statVo)) {
            statVo.setTeamOneName(param.getTeamOneName());
            statVo.setTeamTwoName(param.getTeamTwoName());
        }
        return ResponseRest.suc("personalStat", statVo);
    }

    @Override
    public ResponseRest<RankStatVo> rankList(StatDto param) {
        checkValue(param, "param");
        checkValue(param.getGroupId(), "查询群id不能为空");
        Integer selectType = param.getSelectType();
        List<StatVo> restList = null;
        if (selectType == 0) {
            //总榜
            restList = userGroupRefService.findUserRankListByGroupId(param.getGroupId(), param.getOrderByType(), param.getOrderByTypeDesc(),param.getTeamOneName());
        } else if (selectType == 1) {
            //年榜
            restList = baseMapper.findRankListByGroupId(param.getGroupId(), 1, param.getOrderByType(), param.getOrderByTypeDesc(),param.getTeamOneName());
        } else if (selectType == 2) {
            //半年
            restList = baseMapper.findRankListByGroupId(param.getGroupId(), 2, param.getOrderByType(), param.getOrderByTypeDesc(),param.getTeamOneName());
        }else if (selectType == 3) {
            //月榜
            restList = baseMapper.findRankListByGroupId(param.getGroupId(), 3, param.getOrderByType(), param.getOrderByTypeDesc(),param.getTeamOneName());
        } else if (selectType == 4) {
            //周榜
            restList = baseMapper.findRankListByGroupId(param.getGroupId(), 4, param.getOrderByType(), param.getOrderByTypeDesc(),param.getTeamOneName());
        } else if (selectType == 5) {
            //日榜
            restList = baseMapper.findRankListByGroupId(param.getGroupId(), 5, param.getOrderByType(), param.getOrderByTypeDesc(),param.getTeamOneName());
        }
        Map<Integer, List<StatVo>> rankDataMap = new HashMap<>();
        rankDataMap.put(selectType, restList);

        return ResponseRest.suc("rankList", new RankStatVo(rankDataMap));
    }

    @Override
    public ResponseRest<BoutStatVo> findByImportIdUserId(BoutStatDto param) {
        checkValue(param, "param");
        checkValue(param.getImportRecordId(), "导入记录id不能为空");
        checkValue(param.getUserGroupRefId(), "用户id群关系id不能为空");
        BoutStatVo vo = null;
        List<BoutStat> byParam = baseMapper.findByParam(param.invertEntity());
        if (isNotEmpty(byParam)) {
            BoutStat boutStat = byParam.get(0);
            vo = BoutStatVo.invertToVo(boutStat);
        }
        return ResponseRest.suc("findByImportIdUserId", null);
    }

    /**
     * 修改
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, timeout = 10, rollbackFor = Exception.class)
    public ResponseRest<Boolean> updateBoutStat(BoutStatDto param) throws ProjectException {
        BoutStat boutStat = param.invertEntity();
        EntityUtils.setUpdatedInfo(boutStat);
        boolean bool = this.updateById(boutStat);
        if (bool) {
            RedisUtil.toDelete(RedisEnum.CACHE_TABLE_DATA, "boutStat", "id", param.getId());
        }
        return ResponseRest.suc("updateBoutStat", true);
    }


}
